def increment(number, by):
    return (number, number+by)  # returns a tuple,which is an immutable list


a = increment(2, 3)  # There are by default 2 line-breaks because of Pep8
print(a, type(a))  # (2, 5) <class 'tuple'>
print(a[0:])  # the values should be accessed through []
a = increment(2, by=3)  # this is called a keyword argument


def full_name(first: str, last: str = "Gao") -> str:  # default values, and type
    # str and ->str won't check the type of it
    # it is only a hint
    return f"{first} {last}"


print(full_name(1, 'gao'))

# arbitrary number of arguments
# one way -------------------------------------


def multiply_list(list):
    a = 1
    for b in list:
        a *= b
    return a


print(multiply_list([1, 2, 3, 4]))


# a better way -------------------------------------
def multiply(b=1, *args):
    # args will be a tuple
    print(f"b is {b}", f"args is {args}")
    for number in args:
        b += number
    return b


a = 1
print(multiply(a, 2, 3, 4), a)  # a won't be changed


def save_user(**user):
    # user will be a dictionary
    print(user)


save_user(id=1, name="admin")  # {'id': 1, 'name': 'admin'}
